package com.example.demo.service.impl;

import com.example.demo.config.logInterceptor.Log;
import com.example.demo.service.UserService;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

/**
 * @author shenb
 * @date 2022-07-15 15:05
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private ApplicationContext applicationContext;


    @Override
    @Log("list users")
    public void list() {
        System.out.println("is AOP Proxy: " + AopUtils.isAopProxy(this));
    }



    @SuppressWarnings({"unchecked"})
    protected <T> T getTargetObject(Object proxy) throws Exception {
        while( (AopUtils.isJdkDynamicProxy(proxy))) {
            return (T) getTargetObject(((Advised)proxy).getTargetSource().getTarget());
        }
        return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
    }

    @Override
    @Log("test 1")
    public void test1() {
        testInside();
    }

    @Override
    @Log("test 2")
    public void test2() {
        try {
            UserService targetObject = getTargetObject(this);
            targetObject.testInside();

            UserService us = (UserService) AopContext.currentProxy();
            us.testInside();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    @Log("test 3")
    public void test3() {
        applicationContext.getBean(UserService.class).testInside();
    }

    @Override
    @Log("test inside")
    public void testInside() {

    }
}
